/*
 * Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#include "ScriptedPch.h"
#include "ulduar.h"

const DoorData doorData[] =
{
    {194905,    BOSS_LEVIATHAN, DOOR_TYPE_ROOM,     0},
    {194630,    BOSS_LEVIATHAN, DOOR_TYPE_PASSAGE,  0},
    {194631,    BOSS_XT002,     DOOR_TYPE_ROOM,     0},
    {194553,    BOSS_ASSEMBLY,  DOOR_TYPE_PASSAGE,  0},
    {194554,    BOSS_ASSEMBLY,  DOOR_TYPE_ROOM,     0},
    {194556,    BOSS_ASSEMBLY,  DOOR_TYPE_PASSAGE,  0},
    {194553,    BOSS_KOLOGARN,  DOOR_TYPE_ROOM,     0},
    {194441,    BOSS_HODIR,     DOOR_TYPE_PASSAGE,  0},
    {194634,    BOSS_HODIR,     DOOR_TYPE_PASSAGE,  0},
    {194442,    BOSS_HODIR,     DOOR_TYPE_ROOM,     0},
    {0,         0,              DOOR_TYPE_ROOM,     0}, // EOF
};

struct instance_ulduar : public InstanceData
{
    instance_ulduar(Map* pMap) : InstanceData(pMap)
    {
        SetBossNumber(MAX_BOSS_NUMBER);
        LoadDoorData(doorData);
    }

	uint64 uiLeviathan;
	uint64 uiNorgannon;
	
	uint64 uiIgnis;
    
	uint64 uiRazorscale;
	uint64 uiExpCommander;
	
	uint64 uiXT002;
	
	uint64 m_auiAssemblyGUIDs[3];
    
	uint64 uiKologarn;
	uint64 uiKologarnBridge;
	uint64 uiRightArm;
    uint64 uiLeftArm;

	uint64 uiAuriaya;
    uint64 m_uiMimironGUID;
    uint64 m_uiHodirGUID;
    uint64 m_uiThorimGUID;
    uint64 uiFreya;
    uint64 m_uiVezaxGUID;
    uint64 m_uiYoggSaronGUID;
    uint64 m_uiAlgalonGUID;
	
	uint64 m_uiHarpoon[2];
	uint64 mole_machine[3];

	uint32 mole_count;

	GameObject *KologarnChest;
	GameObject *ThorimChest;
	GameObject *HodirChest;
	GameObject *FreyaChest;

	void Initialize()
    {
		uiLeviathan			= 0;
		uiNorgannon			= 0;
        uiIgnis				= 0;
        
		uiRazorscale		= 0;
		uiExpCommander      = 0;

        uiXT002				= 0;

        uiKologarn			= 0;
        uiKologarnBridge	= 0;
		uiRightArm			= 0;
		uiLeftArm			= 0;

		uiAuriaya			= 0;
        m_uiMimironGUID     = 0;
        m_uiHodirGUID       = 0;
        m_uiThorimGUID      = 0;
        uiFreya				= 0;
        m_uiVezaxGUID       = 0;
        m_uiYoggSaronGUID   = 0;
        m_uiAlgalonGUID     = 0;

        KologarnChest       = 0;
        ThorimChest         = 0;
        HodirChest          = 0;
        FreyaChest          = 0;

		mole_count          = 0;
		

        memset(&m_auiAssemblyGUIDs, 0, sizeof(m_auiAssemblyGUIDs));
    }


    void OnGameObjectCreate(GameObject* pGo, bool add)
    {
		AddDoor(pGo, add);

		switch(pGo->GetEntry()) {
            case GO_Kologarn_CHEST_HERO: KologarnChest = add ? pGo : NULL; break;
            case GO_Kologarn_CHEST: KologarnChest = add ? pGo : NULL; break;
			case GO_Kologarn_BRIDGE: uiKologarnBridge = pGo->GetGUID(); HandleGameObject(NULL, true, pGo); break;
            case GO_Thorim_CHEST_HERO: ThorimChest = add ? pGo : NULL; break;
            case GO_Thorim_CHEST: ThorimChest = add ? pGo : NULL; break;
            case GO_Hodir_CHEST_HERO: HodirChest = add ? pGo : NULL; break;
            case GO_Hodir_CHEST: HodirChest = add ? pGo : NULL; break;
            case GO_Freya_CHEST_HERO: FreyaChest = add ? pGo : NULL; break;
            case GO_Freya_CHEST: FreyaChest = add ? pGo : NULL; break;
			case GO_HARPOON:
				mole_machine[mole_count] = pGo->GetGUID();
				HandleGameObject(NULL, false, pGo);
				mole_count++;
				if (mole_count == 3) mole_count = 0;
				break;
		}
    }

    void OnCreatureCreate(Creature* pCreature, bool add) {
        switch(pCreature->GetEntry()) {
            case NPC_IGNIS: 
				uiIgnis = pCreature->GetGUID(); 
				break;
            case NPC_XT002: 
				uiXT002 = pCreature->GetGUID(); 
				break;
			case NPC_LEVIATHAN:
				uiLeviathan = pCreature->GetGUID(); 
				break;
            case NPC_NORGANNON: 
				uiNorgannon = pCreature->GetGUID();
				break;
			case NPC_RAZORSCALE: 
				uiRazorscale = pCreature->GetGUID(); 
				break;

			// Assembly of Iron
            case NPC_STEELBREAKER:
                m_auiAssemblyGUIDs[0] = pCreature->GetGUID();
                break;
            case NPC_MOLGEIM:
                m_auiAssemblyGUIDs[1] = pCreature->GetGUID();
                break;
            case NPC_BRUNDIR:
                m_auiAssemblyGUIDs[2] = pCreature->GetGUID();
                break;
            case NPC_KOLOGARN:
                uiKologarn = pCreature->GetGUID();
                break;
			case NPC_RIGHTARM: 
				uiRightArm = pCreature->GetGUID(); 
				break;
            case NPC_LEFTARM: 
				uiLeftArm = pCreature->GetGUID(); 
				break;
            case NPC_AURIAYA:
                uiAuriaya = pCreature->GetGUID();
                break;
            case NPC_MIMIRON:
                m_uiMimironGUID = pCreature->GetGUID();
                break;
            case NPC_HODIR:
                m_uiHodirGUID = pCreature->GetGUID();
                break;
            case NPC_THORIM:
                m_uiThorimGUID = pCreature->GetGUID();
                break;
            case NPC_FREYA:
                uiFreya = pCreature->GetGUID();
                break;
            case NPC_VEZAX:
                m_uiVezaxGUID = pCreature->GetGUID();
                break;
            case NPC_YOGGSARON:
                m_uiYoggSaronGUID = pCreature->GetGUID();
                break;
            case NPC_ALGALON:
                m_uiAlgalonGUID = pCreature->GetGUID();
                break;

			case NPC_COMMANDER:
				uiExpCommander = pCreature->GetGUID();
				break;
        }

        AddMinion(pCreature, add);
    }

    uint64 GetData64(uint32 id) {
        switch(id) {
		case DATA_LEVIATHAN:
            return uiLeviathan;
		case DATA_NORGANNON:
            return uiNorgannon;
        case DATA_IGNIS:
            return uiIgnis;
		case DATA_RAZORSCALE:
			return uiRazorscale;
		case DATA_COMMANDER:
			return uiExpCommander;
        case DATA_XT002:
            return uiXT002;
        case DATA_KOLOGARN:
            return uiKologarn;
		case DATA_RIGHT_ARM:
            return uiRightArm;
        case DATA_LEFT_ARM:
            return uiLeftArm;
        case DATA_AURIAYA:
            return uiAuriaya;
        case DATA_MIMIRON:
            return m_uiMimironGUID;
        case DATA_HODIR:
            return m_uiMimironGUID;
        case DATA_THORIM:
            return m_uiThorimGUID;
        case DATA_FREYA:
            return uiFreya;
        case DATA_VEZAX:
            return m_uiVezaxGUID;
        case DATA_YOGGSARON:
            return m_uiYoggSaronGUID;
        case DATA_ALGALON:
            return m_uiAlgalonGUID;

        // Assembly of Iron
        case DATA_STEELBREAKER:
            return m_auiAssemblyGUIDs[0];
        case DATA_MOLGEIM:
            return m_auiAssemblyGUIDs[1];
        case DATA_BRUNDIR:
            return m_auiAssemblyGUIDs[2];

		

        }
        return 0;
    }

    bool SetBossState(uint32 id, EncounterState state)
    {
        if (!InstanceData::SetBossState(id, state))
            return false;

		if (id == BOSS_KOLOGARN && state == DONE)
        {
            HandleGameObject(uiKologarnBridge, false);
            KologarnChest->SetRespawnTime(KologarnChest->GetRespawnDelay());
        }
        
        if (id == BOSS_HODIR && state == DONE)
        {
            HodirChest->SetRespawnTime(HodirChest->GetRespawnDelay());
        }
        return true;
    }
};

InstanceData* GetInstanceData_instance_ulduar(Map* pMap)
{
    return new instance_ulduar(pMap);
}

void AddSC_instance_ulduar()
{
    Script *newscript;
    newscript = new Script;
    newscript->Name = "instance_ulduar";
    newscript->GetInstanceData = &GetInstanceData_instance_ulduar;
    newscript->RegisterSelf();
}